עבודה עם STL. )Dmitry Korolev

Similar documents
לתיכנות עם MATLAB Lecture 5: Boolean logic and Boolean expressions

לתיכנות עם MATLAB Lecture 5: Boolean logic and Boolean expressions

Practical Session No. 14 Topological sort,amortized Analysis

Algorithms. Intro2CS week 5

ספרית התבניות הסטנדרטית (STL) כתיבת אלגוריתמים גנריים מצביעים חכמים. .vector. list iterator נכיר תחילה את האוסף הפשוט ביותר בספריה

לתיכנות עם MATLAB Lecture 5: Boolean logic and Boolean expressions

Amortized Analysis, Union-Find,

תרגול 12. Standard Template Library כתיבת אלגוריתמים גנריים מצביעים חכמים

מערכים שעור מס. 4 כל הזכויות שמורות דר ' דרור טובי המרכז האוניברסיטאי אריאל 1

מבוא למדעי המחשב תרגול 13: עצים בינאריים

תזכורת: עץבינארי מבוא למדעי המחשב הרצאה 24: עצי חיפוש בינאריים

Practical Session - Heap

מצליחה. 1. int fork-bomb() 2. { 3. fork(); 4. fork() && fork() fork(); 5. fork(); printf("bla\n"); 8. return 0; 9. }

תור שימושים בעולם התוכנה

רזח יליגרתו םי יראני ב ם

מבוא לתכנות בשפת C. Tzachi (Isaac) Rosen

משתנים שעור מס. 2 כל הזכויות שמורות דר ' דרור טובי המרכז האוניברסיטאי אריאל 1

ת ונכת סרוק תורשוקמ תומישר :יעישת רועיש 1

מבוא למדעי המחשב תרגול 8 רשימה משורשרת כללית, Comparator

סכום (סדרת ערכים) אחרת - דוגמא: סכום-ספרות (num) אם < 10 num החזר 1 או אם = 0 = num החזר 0 public static int numofdigits (int num)

תוכנה 1 סמסטר א' תשע"א

תוכנה 1 * לא בהכרח בסדר הזה

תכנות מונחה עצמים משחקים תשע"ו

רשימות דילוגים Skip Lists

תוכנה 1 תרגול 2: מערכים ומבני בקרה

Programming for Engineers in Python

Programming for Engineers in Python

הנכות 1 םוכיס לוגרת 13 1

Engineering Programming A

ASP.Net Web API.

הנכות 1 תואיגש םע תודדומתהו תואלול,םי : כרעמ 2 לוגרת

Simple Web Service. namespace MyService { public class Service1 : System.Web.Services.WebService {

הנכות 1 תואיגש םע תודדומתהו תואלול,םיכרעמ : לו 2 גרת

תרגול מספר 3: מערכים

תוכנה 1 * לא בהכרח בסדר הזה

Type Aliases. Examples: using newtype = existingtype; // C++11 typedef existingtype newtype; // equivalent, still works

תוכנה 1 בשפת Java נושאים שונים בהורשה רובי בוים ומתי שמרת בית הספר למדעי המחשב אוניברסיטת תל אביב

תוכנה 1 מערכים. Array Creation and Initialization. Array Declaration. Loop through Arrays. Array Creation and Initialization

תרגול 6 רקורסיה ותכנות מונחה עצמים

תוכנה 1 תרגול מספר 13

תוכנה 1 תרגול מספר 13

Due Date: See Blackboard

Computer Programming A תרגול 9

תוכנה 1 תרגול 2: מערכים, מבני בקרה ושגיאות

תוכנה 1. תרגול מספר 11: Static vs. Dynamic Binding מחלקות מקוננות Nested Classes

תוכנה 1 מערכים. Array Creation and Initialization. Array Declaration. Array Creation and Initialization. Loop through Arrays

GridKa School 2013: Effective Analysis C++ Standard Template Library

תוכנה 1 3 תרגול מס' מערכים ומבני בקרה

הנכות 1 םוכיס לוגרת 13 1

Tutorial 10. Introduction to C++ שימו

תרגול 4 פונקציות. מבנה של פונקציה: public static <return value type> <function name> (<arg1 type> <arg1>, <arg2 type> <arg2>, ) { <function body> }

STL components. STL: C++ Standard Library Standard Template Library (STL) Main Ideas. Components. Encapsulates complex data structures and algorithms

Introduction to Programming in C תרגול 8

מבוא לתכנות ב- JAVA מעבדה 2

Graph Database, think different!

STL: C++ Standard Library

תרגול 7 רשימות משורשרות, רקורסיית

Unit 1: Preliminaries Part 4: Introduction to the Standard Template Library

תוכנה 1 מבני נתונים גנריים

פתרון מוצע לבחינת מה"ט ב_שפת c מועד אביב תשע"ח, פברואר 8102 מחבר: מר שייקה בילו, מכללת אורט רחובות

Exams questions examples

קורס תכנות שיעור שישי: מחרוזות, מצביעים

CS11 Advanced C++ Fall Lecture 1

מבוא לתכנות ב- JAVA מעבדה 4

קורס תכנות כתובות בזיכרון כתובות בזכרון מצביעים וכתובות מצביעים וכתובות שיעור שביעי: מבנים, הקצאת זיכרון דינאמית האופרטור &

עצים. מבני נתונים Iterators רשימות מקושרות עצים "רגילות" רקורסיביות

Programming in C++ using STL. Rex Jaeschke

קורס תכנות בשיעור הקודם למדנו על רקורסיה שיעור שישי: מערכים פונקציה רקורסיבית שאלה חישוב נוסחאות רקורסיביות בשפת C

רשימות דילוגים Skip Lists

תרגול 3 מערכים ופונקציות

Today. andyoucanalsoconsultchapters6amd7inthetextbook. cis15-fall2007-parsons-lectvii.1 2

הנכות 1 םוכיס לוגרת 14 1

Due Date: See Blackboard

Templates and Vectors

Practical Session #4 - ADTs: Array, Queue, Stack, Linked List

Nir Adar

Template based set of collection classes STL collection types (container types)

- MEAN Stack חזרה. MongoDB - as the database Express - as the web framework AngularJS - as the frontend framework NodeJS- as the server platform

Communication Networks ( ) / Spring 2011 The Blavatnik School of Computer Science, Tel-Aviv University. Allon Wagner

דף הדרכה ליצירת שרת/ לקוח עם GUI

Chapter 5. The Standard Template Library.

The Standard Template Library Classes

פרק 15 טיפוס חדש: מבנים שימוש במבנים שימוש במבנים שימוש במבנים

Chapter 11.2 Linked lists ( )

תוכנה 1 טיפוסי השפה טיפוסים לא פרימיטיביים הטיפוסים הפרימיטיביים מחרוזות המרה למספרים תרגול 2: טיפוסי שפה, מחרוזות, מערכים ושגיאות

Container Notes. Di erent Kinds of Containers. Types Defined by Containers. C++11 Container Notes C++11

THE STANDARD TEMPLATE LIBRARY (STL) Week 6 BITE 1513 Computer Game Programming

מבני נתונים תכנות מונחה עצמים מבני נתונים. מחלקות אבסטרקטיות חבילות packages סיכום הרשאות גישה wrappers ADT מערך דינמי מחסנית

STL Quick Reference for CS 241

Module 9. Templates & STL

Computational Physics

Arrays - Vectors. Arrays: ordered sequence of values of the same type. Structures: named components of various types

הנכות 1 םוכיס לוגרת 13 1

G52CPP C++ Programming Lecture 18

1. The term STL stands for?

by Pearson Education, Inc. All Rights Reserved. 2

כתבו קוד ב- 3 קבצי ה hpp (כתבו כהערה את שם הקובץ מעל) כך שהקוד יהיה תקין ובסגנון טוב. אין חובה

מבוא למדעי המחשב 2018 תרגול 7

קורס תכנות שיעור שני: שימוש במשתנים,

CS197c: Programming in C++

Transcription:

עבודה עם STL )Dmitry Korolev יניב סבו )מבוסס על המאמר של

הקדמה STL = Standard Template Library הספרייה הסטנדטית של ++C. כוללת את רוב האלגוריתמים ומבני הנתונים הבסיסיים במדעי המחשב. Heavily parameterized כמעט כל רכיב ב STL הוא.template

Containers STL כולל :containers classes מחלקות שתפקידן להכיל אובייקטים אחרים. לדוגמה, STL כולל את המחלקות: deque, vector, list, set, multiset, map, multimap,

לפני שנתחיל כשתוכנית משתמשת ב,STL היא צריכה לכלול את ה headers המתאימית. #include <stack> כל ה- STL מרוכז ב.namespace std using namespace std; כשיוצרים container יש לספק גם את סוג הנתונים שהוא יכיל. vector<int> N; vector< vector<int> > CorrectDefinition; vector<vector<int>> WrongDefinition; // Wrong: compiler may be confused by 'operator >>'

Vector vector<int> v(10); for(int i = 0; i < 10; i++) { v[i] = (i+1)*(i+1); vector<int> v; vector<int> v[10]; וקטור הוא למעשה מערך עם פונקציות נוספות. :C לקוד backward-compatible מה שתי השורות הבאות יעשו? וקטור יכול לדווח על הגודל שלו: int elements_count = v.size(); יש לשים לב כי size() הוא!unsigned

- המשך Vector איך בודקים האם וקטור ריק? bool is_nonempty_notgood = (v.size() >= 0); // Try to avoid this bool is_nonempty_ok =!v.empty(); vector<int> v; for(int i = 1; i < 1000000; i *= 2) { v.push_back(i); :vector vector<int> v(20); for(int i = 0; i < 20; i++) { v[i] = i+1; v.resize(25); for(int i = 20; i < 25; i++) { v.push_back(i*2); // Writes to elements with indices [25..30), not [20..25)! < הכנסת איבר חדש ל פונקציית :resize

- המשך Vector שימוש בהרבה push_back עלול לגרום להקצאות זכרון מיותרות. לדוגמה, עבור וקטור שבו 1000 איברים והגודל המוקצה שלו הוא 1024, אם נוסיף 50 איברים באמצעות push_back נקבל וקטור שהגודל המוקצה שלו הוא.2048 במקום, ניתן להשתמש ב.vector.reserve(1050)

- המשך Vector פונקציית vector.clear() אתחול וקטור: יצירת מערך דו מימדי: - מרוקנת את הוקטור. vector<int> v1; //... vector<int> v2 = v1; vector<int> v3(v1); vector<int> Data(1000); // 1000 zeros after creation vector<string> names(20, Unknown ); vector< vector<int> > Matrix; int N, M; vector< vector<int> > Matrix(N, vector<int>(m, -1)); אתחול מטריצה:

- המשך Vector העברת וקטור כפרמטר לפונקציה: void some_function(vector<int> v) { // Never do it unless you re sure what you do! //... void some_function(const vector<int>& v) { // OK //... int modify_vector(vector<int>& v) { // Correct V[0]++;

Pairs הוא טיפוס המכיל אובייקט אחד מסוג T1 pair<t1, <T2 ואובייקט שני מסוג T2. לדוגמה: pair<string, pair<int,int> > P; string s = P.first; // extract string int x = P.second.first; // extract first int int y = P.second.second; // extract second int היתרון הגדול של pairs הוא שיש להם פונקציית השוואה built-in שמבצעת השוואה קודם לפי המפתח הראשון ואם הם שווים מבצעת השוואה לפי המפתח השני.

Iterators איטרטורים הם המנגנון המאפשר לגשת למידע הנמצא ב containers ומהווים בעצם הכללה של מצביעים. ממומשים בצורה גנרית. איטרטורים רגילים iterators) (normal מאפשרים: לקבל את הערך שמוצבע ע"י האיטרטור: int x = *it להגדיל ולהקטין איטרטורים: it-- it++, להשוות איטרטורים: ==,=! איטרטורים מסוג בנוסף: random access iterators מאפשרים הוספה/החסרה לאיטרטור: it+=20 שקול לביצוע איברים קדימה..int n = it1-it2 קבלת המרחק בין איטרטורים: 20 shift

- המשך Iterators :container לדוגמה הפיכת template<typename T> void reverse_array(t *first, T *last) { if(first!= last) { while(true) { swap(*first, *last); first++; if(first == last) { break; last--; if(first == last) { break; end האלגוריתמים ב STL משתמשים בשני :iterators begin, end כאשר begin מצביע לאיבר הראשון ו מצביע לאיבר האחד אחרי אחרון. לכל container יש שתי פונקציות: end() begin(), שמחזירות את האיטרטורים המתאימים.

- המשך Iterators.c.begin() == c.end() c לכן, ניתן לומר כי ריק אמ"מ עבור containers שהאיטרטורים שלהם הם random.c.end()-c.begin()=c.size() מתקיים: access iterators STL היא: לכן הפונקציה להפיכת container עבור template<typename T> void reverse_array_stl_compliant(t *begin, T *end) { // We should at first decrement 'end' // But only for non-empty range if(begin!= end) { end--; if(begin!= end) { while(true) { swap(*begin, *end); begin++; If(begin == end) { break; end--; if(begin == end) { break;

שימוש ב iterators כל אובייקט עם מספיק פונקציונאליות יכול להיות מועבר לאלגוריתמים ופונקציות של STL )לדוגמה מצביע(. לדוגמה: vector<int> v; //... vector<int> v2(v); vector<int> v3(v.begin(), v.end()); // v3 equals to v2 int data[] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31 ; vector<int> primes(data, data+(sizeof(data) / sizeof(data[0]))); // not recommended vector<int> v; //... vector<int> v2(v.begin(), v.begin() + (v.size()/2)); int data[10] = { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19 ; reverse(data+2, data+6); // the range { 5, 7, 9, 11 is now { 11, 9, 7, 5 ;

- שימוש ב iterators המשך לכל container יש גם את הפונקציות rend() rbegin(), שמחזירות.reverse iterators vector<int> v; vector<int> v2(v.rbegin()+(v.size()/2), v.rend()); כדי ליצור איטרטור עלינו לציין את הטיפוס שעליו הוא מצביע. ניתן לייצר איטרטור עבור container באמצעות הוספת ::reverse_iterator, ::iterator, ::const_iterator,.container לשם ה ::const_reverse_iterator vector<int> v; //... // Traverse all container, from begin() to end() for(vector<int>::iterator it = v.begin(); it!= v.end(); it++) { *it++; // Increment the value iterator is pointing to

אלגוריתמים STL כולל גם אלגוריתמים שניתן להפעיל על איטרטורים. אלגוריתם reverse שראינו. אלגוריתם - find מקבל שני איטרטורים וערך לחיפוש. מחזיר את האיטרטור שמצביע להופעה הראשונה של הערך אם נמצא בין האיטרטורים ואחרת את האיטרטור הסופי )כלומר הימני מבין שני האיטרטורים(. כדי לקבל את אינדקס האיבר שנמצא יש לחסר את האיטרטור של ההתחלה מהתוצאה של.find vector<int> v; if(find(v.begin(), v.end(), 49)!= v.end()) { //...

אלגוריתמים - המשך - min_element, max_element מחזירים את האיטרטור לאיבר המתאים )מקסימלי/מינימלי(. int data[5] = { 1, 5, 2, 4, 3 ; vector<int> X(data, data+5); int v1 = *max_element(x.begin(), X.end()); // Returns value of max element in vector int i1 = min_element(x.begin(), X.end()) X.begin; // Returns index of min element in vector int v2 = *max_element(data, data+5); // Returns value of max element in array int i3 = min_element(data, data+5) data; // Returns index of min element in array - ממיין את האיברים שבין שני האיטרטורים: vector<int> X; Int A[10]; //... sort(x.begin(), X.end()); // Sort array in ascending order sort(a, A+10); // Sort A in ascending order sort(x.rbegin(), X.rend()); // Sort array in descending order using with reverse iterators sort

אלגוריתמים - המשך מה נעשה אם נרצה למיין טיפוסים לא פרמיטיביים? sort() מבוסס על אותה טכניקה שמופיעה בכל המקומות הרלוונטיים ב- STL : השוואות מתבצעות באמצעות אופרטור >. struct fraction { int n, d; // (n/d) bool operator < (const fraction& f) const { return n*f.d < f.n*d; ; vector<fraction> v; sort(all(v));

אלגוריתמים - המשך מה נעשה אם נרצה למיין במספר צורות את אותו טיפוס? typedef pair<double, double> dd; const double epsilon = 1e-6; struct sort_by_polar_angle { dd center; template<typename T> sort_by_polar_angle(t b, T e) { //. bool operator () (const dd& a, const dd& b) const { double p1 = atan2(a.second-center.second, a.first-center.first); double p2 = atan2(b.second-center.second, b.first-center.first); return p1 + epsilon < p2; ; vector<dd> points; sort(points.begin(), points.end(), sort_by_polar_angle(points.begin(), points.end()));

אלגוריתמים - המשך אלגוריתמים נוספים: b).max(a, b), min(a, b), swap(a, אלגוריתמים שימושיים נוספים הם next_permutation, next_permutation(begin, end).prev_permutation מכניס לתחום end) (begin, את הפרומטציה הבאה של אותם איברים, או מחזירה false אם זו האחרונה. vector<int> v; for(int i = 0; i < 10; i++) { v.push_back(i); do { Solve(..., v); while(next_permutation(v.begin(), v.end());

אלגוריתמים - המשך אלגוריתם to_begin) copy(from_begin, from_end, מעתיק איברים מהתחום הראשון לשני. בתחום השני צריך להיות מספיק מקום. vector<int> v1; vector<int> v2; //... // Now copy v2 to the end of v1 v1.resize(v1.size() + v2.size()); // Ensure v1 have enough space copy(v2.begin(), v2.end(), v1.end() - v2.size()); // Copy v2 elements right after v1 ones

הערות void f(const vector<int>& v) { הקוד הבא ייצור שגיאה: for( vector<int>::iterator it = v.begin(); // hm... where s the error?.. //... הקוד הנכון נראה כך: void f(const vector<int>& v) { int r = 0; for(vector<int>::const_iterator it = v.begin(); it!= v.end(); it++) //

הערות - המשך #define sz(a) int((a).size()) #defile all(c) (c).begin(),(c).end() #define tr(c,i) for(typeof((c).begin()) i = (c).begin(); i!= (c).end(); i++) #define present(c,x) ((c).find(x)!= (c).end()) #define cpresent(c,x) (find(all(c),x)!= (c).end()) void f(const vector<int>& v) { int r = 0; tr(v, it) { r += (*it)*(*it); return r; מאקרויים שימושיים )?(: המאקרו tr מאפשר לבצע איטרציה על איברי כל container בקלות. לדוגמה:

שינוי המידע ב Vector vector<int> v; //... :insert() v.insert(1, 42); // Insert value 42 after the first iterator ניתן להכניס איבר לוקטור באמצעות יש לשים לב כי insert של vector גורם להזזת איברים ולכן מומלץ להכניס מספר איברים בפקודה אחת: vector<int> v; vector<int> v2; //.. // Shift all elements from second to last to the appropriate number of elements. // Then copy the contents of v2 into v. v.insert(1, all(v2)); erase(iterator); erase(begin iterator, end iterator); לוקטור יש גם פונקציית :erase

String.strings יש ל STL container מיוחד לעבודה עם string של STL מאפשר מספר פעולות חשובות כמו שרשור,)s1+s2( קלט של מחרוזת )s )cin << ופעולות רבות נוספות. string s = "hello"; string s1 = s.substr(0, 3), // "hel" s2 = s.substr(1, 3), // "ell" s3 = s.substr(0, s.length()-1), // "hell" s4 = s.substr(1); // "ello" מה יקרה כאשר = 0 s.length()?

Set עץ אדום שחור מאפשר הוספה, מחיקה וחיפוש של איברים ב.O(logN) העץ לא יכול להכיל איברים כפולים. מספר האיברים ב set מוחזר בסיבוכיות (1)O. set<int> s; for(int i = 1; i <= 100; i++) { s.insert(i); // Insert 100 elements, [1..100] s.insert(42); // does nothing, 42 already exists in set for(int i = 2; i <= 100; i += 2) { s.erase(i); // Erase even values int n = int(s.size()); // n will be 50.set כמובן שלא ניתן לבצע push_back() על

- המשך Set מעבר על האיברים בסדר עולה: // Calculate the sum of elements in set set<int> S; //... int r = 0; for(set<int>::const_iterator it = S.begin(); it!= S.end(); it++) { r += *it; ניתן גם להשתמש במאקרו שהגדרנו: set< pair<string, pair< int, vector<int> > > SS; int total = 0; tr(ss, it) { total += it->second.first;

- המשך Set אסור להשתמש באלגוריתם find של STL כדי לחפש איבר ב - set זה יתבצע ב.O(n) במקום זאת יש לקרוא ל.set::find set::find מחזיר איטרטור לאיבר שנמצא, או end() אם לא נמצא. set<int> s; //... if(s.find(42)!= s.end()) { // 42 presents in set else { // 42 not presents in set

- המשך Set.erase כדי למחוק איבר מה set משתמשים ב set<int> s; // s.insert(54); s.erase(29); set<int> s; // s.insert(54); s.erase(29); set יכול גם לקבל מערך ב.constructor ניתן להשתמש בזה כדי להסיר כפילויות ולמיין במהירות: vector<int> v; // set<int> s(all(v)); vector<int> v2(all(s));

Map דומה מאוד ל,set אך הוא מכיל זוגות value>.pair<key, יכול להיות לכל היותר pair אחד עם אותו.key ב map<string, int> M; M["Top"] = 1; M["Coder"] = 2; M["SRM"] = 10; int x = M["Top"] + M["Coder"]; if(m.find("srm")!= M.end()) { M.erase(M.find("SRM")); // or even M.erase("SRM") map<string, int> M; // int r = 0; tr(m, it) { r += it->second; :keys.map map map map האופרטור [] מוגדר על ניתן לבצע מעבר על לפי סדר ה

- המשך Map יש הבדל משמעותי בין find() לאופרטור [] - find לא משנה את התוכן של,map בעוד שהאופרטור [] יוצר איבר אם הוא לא נמצא ב.map void f(const map<string, int>& M) { if(m["the meaning"] == 42) { // Error! Cannot use [] on const map objects! if(m.find("the meaning")!= M.end() && M.find("the meaning")->second == 42) { // Correct cout << "Don't Panic!" << endl; כשעובדים עם set ו- map, אין לשנות את הערך של האיברים באמצעות האיטרטורים!

שימוש באובייקטים שונים ב map/set שוב, לפי אותו כלל: השוואות מבוצעות באמצעות אופרטור >. const double epsilon = 1e-7; struct point { double x, y; // Declare operator < taking precision into account bool operator < (const point& p) const { if(x < p.x - epsilon) return true; if(x > p.x + epsilon) return false; if(y < p.y - epsilon) return true; if(y > p.y + epsilon) return false; return false; ; כעת ניתן ליצור set<point> או.map<point,string>

hash_set / hash_map hash_set, hash_map יעילים כאשר אנו מעוניינים לבדוק האם איבר נמצא ב container )למימוש,)dictionaries אך אין בהם חשיבות לסדר. char*, hash ב- STL.int ישנן פונקציות לחלק מהטיפוסים:

- המשך hash_set / hash_map hash_set<int> a_hash_set(size); hash_map<int, int> a_hash_map(size); hash_set<element, hash_elem, eq_elem> elem_hash_set(size); hash_map<element, int, hash_elem, eq_elem> elem_hash_map(size); struct element { int kuku; int kaka; char str[char_arr_size]; ; struct hash_elem { hash<int> h; size_t operator()(const element& e) const { return (h.operator ()(e.kaka)<<16)+h.operator ()(e.kuku); ; struct eq_elem { bool operator()(const element& e1, const element& e2) const { for(int i = 0; i < CHAR_ARR_SIZE; i++) if (e1.str[i]!= e2.str[i]) return false; return e1.kuku == e2.kuku && (e1.kuku == e2.kuku); ;

String Streams istringstream, void f(const string& s) { // Construct an object to parse strings istringstream is(s); לעיתים יש צורך לעבד.strings ++C מספקת שני אובייקטים לכך:.ostringstream // Vector to store data vector<int> v; // Read integer while possible and add it to the vector int tmp; while(is >> tmp) { v.push_back(tmp);

- המשך String Streams string f(const vector<int>& v) { // Construct an object to do formatted output ostringstream os; // Copy all elements from vector<int> to string stream as text tr(v, it) { os << ' ' << *it; // Get string from string stream string s = os.str(); // Remove first space character if(!s.empty()) { // Beware of empty string here s = s.substr(1); return s;

DFS ברי הגעה מ- s. שהם אלגוריתם לגילוי כל הצמתים ב- V בנוסף מאפשר למצוא האם יש מעגלים בעץ, טופולוגי, למצוא רכיבים קשירים היטב. לבצע מיון הרעיון: בכל שלב האלגוריתם מנסה להתקדם לעומק - כאשר נבקר בצומת v, אם יש קשת (v,u) לצומת u שעוד לא נתגלתה נבקר בה ונמשיך את החיפוש ממנה.

DFS using STL typedef vector<int> vi; typedef vector<vi> vvi; int N; // number of vertices vvi W; // graph vi V; // V is a visited flag void dfs(int i) { if(!v[i]) { V[i] = true; for_each(all(w[i]), dfs); bool check_graph_connected_dfs() { int start_vertex = 0; V = vi(n, false); dfs(start_vertex); return (find(all(v), 0) == V.end());

BFS ברי הגעה מ- s. שהם אלגוריתם לגילוי כל הצמתים ב- V בנוסף מאפשר למצוא את המרחק הקצר ביותר )בקשתות( מ- s לכל צומת ב- V. הרעיון: בכל איטרציה האלגוריתם בוחן חזית של צמתים במרחק i מ- s. יש לגלות את כל הצמתים במרחק i מ- s לפני גילוי צומת במרחק 1+i.

BFS using STL int N; // number of vertices vvi W; // lists of adjacent vertices bool check_graph_connected_bfs() { int start_vertex = 0; vi V(N, false); queue<int> Q; Q.push(start_vertex); V[start_vertex] = true; while(!q.empty()) { int i = Q.front(); // get the tail element from queue Q.pop(); tr(w[i], it) { if(!v[*it]) { V[*it] = true; Q.push(*it); return (find(all(v), 0) == V.end());

Dijkstra.s קלט: גרף ממושקל מכוון ללא קשתות שליליות וצומת.d[v] = dist(s,v) פלט: v לכל צומת

Dijkstra pseudo code /* Initialization: set every distance to INFINITY until we discover a path */ for i = 0 to V - 1 end dist[i] = INFINITY prev[i] = NULL /* The distance from the source to the source is defined to be zero */ dist[s] = 0 /* This loop corresponds to sending out the explorers walking the paths, where * the step of picking "the vertex, v, with the shortest path to s" corresponds * to an explorer arriving at an unexplored vertex */ for each edge of v, (v1, v2) /* The next step is sometimes given the confusing name "relaxation" if(dist[v1] + length(v1, v2) < dist[v2]) dist[v2] = dist[v1] + length(v1, v2) prev[v2] = v1 possibly update U, depending on implementation end if end for end while while(f is missing a vertex) pick the vertex, v, in U with the shortest path to s add v to F

- המשך Dijkstra קל מאוד לממש את האלגוריתם של dijkstra מערך מרחקים בסיבוכיות ) 2.O(V בעזרת עבור גרפים דלילים ניתן לממש את האלגוריתם בסיבוכיות O(ElogV) באמצעות ערימה שתומכת ב decrease key )בעזרת ערימות פיבונצ'י ניתן אף לממש בסיבוכיות.)O(E+VlogV) לצערנו, בערימה של )priority_queue( STL אין פונקציית.decrease key מה נעשה?

Dijkstra using STL vi D(N, 987654321); // distance from start vertex to each vertex priority_queue<ii,vector<ii>, greater<ii> > Q; // priority_queue with reverse comparison operator, // so top() will return the least distance // initialize the start vertex, suppose it s zero D[0] = 0; Q.push(ii(0,0)); // iterate while queue is not empty while(!q.empty()) { // fetch the nearest element ii top = Q.top(); Q.pop(); // v is vertex index, d is the distance int v = top.second, d = top.first; // this check is very important // we analyze each vertex only once // the other occurrences of it on queue (added earlier) // will have greater distance if(d <= D[v]) { // iterate through all outcoming edges from v tr(g[v], it) { int v2 = it->first, cost = it->second; if(d[v2] > D[v] + cost) { // update distance if possible D[v2] = D[v] + cost; // add the vertex to queue Q.push(ii(D[v2], v2));